#include "sock.hpp"
#include <sys/select.h>
#define NUM 1024

// 保存文件描述符的数组
int arr_rfds[NUM];
void Recv(const int &fd)
{
  char buffer[NUM];
  memset(buffer, 0, NUM);
  ssize_t s = recv(fd, buffer, NUM - 1, 0);
  if (s > 0)
    cout << buffer << endl;
  if (s == 0)
  {
    cout << "关闭连接" << fd << endl;
    close(fd);
    for (size_t i = 0; i < NUM; i++)
    {
      if (arr_rfds[i] == fd)
      {
        arr_rfds[i] = -1;
        break;
      }
    }
  }
  if (s < 0)
    cout << "recv fail" << strerror(errno) << endl;
}
void handlsock(const int &listensock, const sock &s, const fd_set &rfds)
{
  if (FD_ISSET(arr_rfds[0], &rfds))
  {
    int fd = s.Accept();
    size_t i = 1;
    for (; i < NUM; i++)
    {
      if (arr_rfds[i] == -1)
      {
        arr_rfds[i] = fd;
        break;
      }
    }
    if (i == NUM)
    {
      cout << "数组满了，请扩容" << endl;
      exit(1);
    }
  }
  for (size_t i = 1; i < NUM; i++)
  {
    if (FD_ISSET(arr_rfds[i], &rfds))
      Recv(arr_rfds[i]);
  }
}
int main()
{
  // 文件描述符的最大值
  int maxfd = 0;
  for (size_t i = 0; i < NUM; i++)
    arr_rfds[i] = -1;
  // 创建套接字
  sock s;
  s.Bind();
  s.Listen();
  // 等待监听listen套接字
  arr_rfds[0] = s._listensock;
  maxfd = s._listensock;
  fd_set rfds;
  // 开始连接
  while (true)
  {
    // 每次重新设定maxfd
    maxfd = 0;
    // 重设rfds位图
    FD_ZERO(&rfds);
    // 遍历数组，位图中插入文件描述符
    for (size_t i = 0; i < NUM; i++)
    {
      if (arr_rfds[i] != -1)
      {
        FD_SET(arr_rfds[i], &rfds);
        cout << arr_rfds[i] << " ";
        if (maxfd < arr_rfds[i])
          maxfd = arr_rfds[i];
      }
    }
    cout << endl;
    //  开始阻塞等待
    int n = select(maxfd + 1, &rfds, nullptr, nullptr, nullptr);
    switch (n)
    {
    case 0:
      cout << "timeout..." << endl;
      break;
    case -1:
      cout << "select fail:" << strerror(errno) << endl;
      break;
    default:
      // 进行区别是连接还是普通套接字的数据就绪
      handlsock(s._listensock, s, rfds);
      break;
    }
  }
  return 0;
}
// int arr_rfds[NUM];
// void Recv(const int &fd)
// {
//   char buffer[NUM];
//   memset(buffer, 0, NUM);
//   recv(fd, buffer, NUM - 1, 0);
//   cout << buffer << endl;
// }
// void handlsock(const int &listensock, const sock &s, const fd_set &rfds)
// {
//   for (size_t i = 0; i < NUM; i++)
//   {
//     if (FD_ISSET(arr_rfds[i], &rfds) == listensock)
//     {
//       int fd = s.Accept();
//       for (size_t j = 0; j < NUM; j++)
//       {
//         if (arr_rfds[j] == -1)
//         {
//           arr_rfds[j] = fd;
//           break;
//         }
//       }
//     }
//     if (FD_ISSET(arr_rfds[i], &rfds) != -1)
//       Recv(arr_rfds[i]);
//   }
// }
// int main()
// {
//   //文件描述符的最大值
//   int maxfd=0;
//   for (size_t i = 0; i < NUM; i++)
//     arr_rfds[i] = -1;
//   // 创建套接字
//   sock s;
//   s.Bind();
//   s.Listen();
//   // 等待监听listen套接字
//   arr_rfds[0] = s._listensock;
//   maxfd=s._listensock;
//   fd_set rfds;

//   // 开始连接
//   while (true)
//   {
//     // 重设rfds位图
//     FD_ZERO(&rfds);
//     for (size_t i = 0; i < NUM; i++)
//     {
//       if (arr_rfds[i] != -1)
//       {
//         FD_SET(arr_rfds[i], &rfds);
//         cout << arr_rfds[i] << " ";
//       }
//       cout << endl;
//     }
//     // 开始阻塞等待
//     int n = select(4, &rfds, nullptr, nullptr, nullptr);
//     switch (n)
//     {
//     case 0:
//       cout << "timeout..." << endl;
//       break;
//     case -1:
//       cout << "select fail:" << strerror(errno) << endl;
//       break;
//     default:
//       // 进行区别是连接还是普通套接字的数据就绪
//       handlsock(s._listensock, s, rfds);
//       break;
//     }
//   }
//   return 0;
// }
